using System;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Matrix.ServiceDiscovery.Entities;
using Matrix.ServiceDiscovery.Consts;

namespace Matrix.ServiceDiscovery
{
    [ConnectionStringName("Default")]
    public class ServiceDiscoveryDbContext : AbpDbContext<ServiceDiscoveryDbContext>
    {
        public DbSet<ServiceInfo> ServiceInfos { get; set; } = null!;
        public DbSet<ServiceInstance> ServiceInstances { get; set; } = null!;
        public DbSet<LoadBalancingConfig> LoadBalancingConfigs { get; set; } = null!;
        public DbSet<HealthCheckRecord> HealthCheckRecords { get; set; } = null!;

        public ServiceDiscoveryDbContext(DbContextOptions<ServiceDiscoveryDbContext> options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.ConfigureServiceDiscovery();
        }
    }

    public static class ServiceDiscoveryDbContextModelCreatingExtensions
    {
        public static void ConfigureServiceDiscovery(this ModelBuilder builder)
        {
            // 配置ServiceInfo
            builder.Entity<ServiceInfo>(b =>
            {
                b.ToTable("ServiceDiscoveryServices", "Matrix");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.Name)
                    .IsRequired()
                    .HasMaxLength(ServiceInfoConsts.MaxNameLength);

                b.Property(x => x.Version)
                    .IsRequired()
                    .HasMaxLength(ServiceInfoConsts.MaxVersionLength);

                b.Property(x => x.Description)
                    .HasMaxLength(ServiceInfoConsts.MaxDescriptionLength);

                b.Property(x => x.ServiceGroup)
                    .HasMaxLength(ServiceInfoConsts.MaxServiceGroupLength);

                // 配置索引
                b.HasIndex(x => x.Name);
                b.HasIndex(x => new { x.Name, x.Version });
                b.HasIndex(x => x.ServiceType);
                b.HasIndex(x => x.Status);
            });

            // 配置ServiceInstance
            builder.Entity<ServiceInstance>(b =>
            {
                b.ToTable("ServiceDiscoveryInstances", "Matrix");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.ServiceName)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Host)
                    .IsRequired()
                    .HasMaxLength(ServiceInstanceConsts.MaxHostLength);

                b.Property(x => x.Protocol)
                    .IsRequired()
                    .HasMaxLength(ServiceInstanceConsts.MaxProtocolLength);

                b.Property(x => x.Region)
                    .HasMaxLength(ServiceInstanceConsts.MaxRegionLength);

                b.Property(x => x.Zone)
                    .HasMaxLength(ServiceInstanceConsts.MaxZoneLength);

                // 配置外键关系
                b.HasOne<ServiceInfo>()
                    .WithMany()
                    .HasForeignKey(x => x.ServiceId)
                    .OnDelete(DeleteBehavior.Cascade);

                // 配置索引
                b.HasIndex(x => x.ServiceId);
                b.HasIndex(x => x.ServiceName);
                b.HasIndex(x => new { x.ServiceName, x.InstanceId });
                b.HasIndex(x => x.HealthStatus);
            });

            // 配置LoadBalancingConfig
            builder.Entity<LoadBalancingConfig>(b =>
            {
                b.ToTable("ServiceDiscoveryLoadBalancingConfigs", "Matrix");

                b.ConfigureByConvention();

                // 配置外键关系
                b.HasOne<ServiceInfo>()
                    .WithOne()
                    .HasForeignKey<LoadBalancingConfig>(x => x.ServiceId)
                    .OnDelete(DeleteBehavior.Cascade);

                // 配置索引
                b.HasIndex(x => x.ServiceId);
                b.HasIndex(x => x.Strategy);
            });

            // 配置HealthCheckRecord
            builder.Entity<HealthCheckRecord>(b =>
            {
                b.ToTable("ServiceDiscoveryHealthCheckRecords", "Matrix");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.CheckType)
                    .IsRequired()
                    .HasMaxLength(50);

                b.Property(x => x.CheckEndpoint)
                    .IsRequired()
                    .HasMaxLength(500);

                b.Property(x => x.ErrorMessage)
                    .HasMaxLength(1000);

                // 配置外键关系
                b.HasOne<ServiceInstance>()
                    .WithMany()
                    .HasForeignKey(x => x.ServiceInstanceId)
                    .OnDelete(DeleteBehavior.Cascade);

                // 配置索引
                b.HasIndex(x => x.ServiceInstanceId);
                b.HasIndex(x => x.CheckTime);
                b.HasIndex(x => new { x.ServiceInstanceId, x.CheckTime });
            });
        }
    }
}